package com.hudson.plugin.result.collector.server.datastore.internal;

import com.hudson.plugin.result.collector.server.datastore.dao.BuildsEntityJpaController;
import com.hudson.plugin.result.collector.server.datastore.dao.HudsonsEntityJpaController;
import com.hudson.plugin.result.collector.server.datastore.dao.ProjectsEntityJpaController;
import com.hudson.plugin.result.collector.server.datastore.dao.ViewsEntityJpaController;
import com.hudson.plugin.result.collector.server.datastore.internal.entity.BuildsEntity;
import com.hudson.plugin.result.collector.server.datastore.internal.entity.HudsonsEntity;
import com.hudson.plugin.result.collector.server.datastore.internal.entity.ProjectsEntity;
import com.hudson.plugin.result.collector.server.datastore.internal.entity.ViewsEntity;
import com.hudson.plugin.result.collector.server.datastore.service.ReportDBService;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: yuxinlei
 * Date: 4/13/11
 * Time: 1:43 PM
 */
public class ReportDBServiceImpl implements ReportDBService {
    private static final Logger logger = LoggerFactory.getLogger(ReportDBServiceImpl.class);
    @Autowired
    private HudsonsEntityJpaController hudsonsJpaController;
    @Autowired
    private ViewsEntityJpaController viewsEntityJpaController;
    @Autowired
    private ProjectsEntityJpaController projectsEntityJpaController;
    @Autowired
    private BuildsEntityJpaController buildsEntityJpaController;

    public Map<String, String> storeToDB(Map<String, Map<String, String>> valuePairsContainer) throws Exception {
        Map<String, String> commonValuePairs = valuePairsContainer.get("commonValuePairs");

        return storeCommonDataDB(commonValuePairs);
    }

    public Map<String, String> storeCommonDataDB(Map<String, String> valuePairs) throws Exception {
        logger.debug("start to store the hudson data in to database .");

        HudsonsEntity hudsonsEntity = updateOrCreateHudsonEntity(valuePairs);
        // ViewsEntity viewsEntity = updateOrCreateViewsEntity(valuePairs, hudsonsEntity);
        ProjectsEntity projectsEntity = updateOrCreateProjectsEntity(valuePairs, hudsonsEntity, null);

        BuildsEntity buildsEntity = createBuildsEntity(valuePairs, hudsonsEntity, null, projectsEntity);
        updatePluginTable(valuePairs, hudsonsEntity, null, projectsEntity, buildsEntity);
        logger.debug("start to retrive all the build in current project which id is " + projectsEntity.getId());
        List<String> numbers = getBuildsEntityJpaController().findProjectAllBuildsNumber(projectsEntity);
        String period = "100";
        String contains = "100";
        ObjectMapper mapper = new ObjectMapper();
        String jsonNumbers = mapper.writeValueAsString(numbers);
        Map<String, String> resultMap = new HashMap<String, String>();
        resultMap.put("numbers", jsonNumbers);
        resultMap.put("period", period);
        resultMap.put("contains", contains);
        return resultMap;
    }

    private HudsonsEntity updateOrCreateHudsonEntity(Map<String, String> valuePairs) throws Exception {
        logger.debug("start to updateOrCreateHudsonEntity .");
        Integer hudsonId;
        HudsonsEntity tempHudsonsEntity = new HudsonsEntity();
        tempHudsonsEntity.setSlaves(valuePairs.get("hudsonSlave"));
        tempHudsonsEntity.setDescription(valuePairs.get("teamFoundation"));
        tempHudsonsEntity.setUrl(valuePairs.get("hudsonUrl"));
        if (getHudsonsJpaController().findHudsonsEntity(valuePairs.get("hudsonUrl")).size() != 0) {

            hudsonId = getHudsonsJpaController().findHudsonsEntity(valuePairs.get("hudsonUrl")).get(0);
            //for update
            tempHudsonsEntity.setId(hudsonId);
            HudsonsEntity compareEntity = getHudsonsJpaController().findHudsonsEntity(hudsonId);
            if (!tempHudsonsEntity.equals(compareEntity)) {
                logger.debug("start to update HudsonEntity .");
                getHudsonsJpaController().edit(tempHudsonsEntity);
            }
        } else {
            getHudsonsJpaController().create(tempHudsonsEntity);
            hudsonId = getHudsonsJpaController().findHudsonsEntity(valuePairs.get("hudsonUrl")).get(0);
        }
        return getHudsonsJpaController().findHudsonsEntity(hudsonId);

    }

    private ViewsEntity updateOrCreateViewsEntity(Map<String, String> valuePairs, HudsonsEntity hudsonsEntity) throws Exception {
        logger.debug("start to updateOrCreateViewsEntity .");
        Integer viewid;

        ViewsEntity tempViewsEntity = new ViewsEntity();
        tempViewsEntity.setVersion(valuePairs.get("icafeVersion"));
        tempViewsEntity.setViewName(valuePairs.get("viewName"));
        tempViewsEntity.setHudsonsByHudsonId(hudsonsEntity);
        tempViewsEntity.setIcafeProject(valuePairs.get("icafeProject"));
        tempViewsEntity.setModule(valuePairs.get("icafeModule"));
        tempViewsEntity.setUrl(valuePairs.get("viewUrl"));
        if (getViewsEntityJpaController().findViewsEntityByModuleAndIcafeProject(valuePairs.get("icafeModule"), valuePairs.get("icafeProject")).size() != 0) {
            viewid = getViewsEntityJpaController().findViewsEntityByModuleAndIcafeProject(valuePairs.get("icafeModule"), valuePairs.get("icafeProject")).get(0);
            //for update
            tempViewsEntity.setId(viewid);
            ViewsEntity compareEntity = getViewsEntityJpaController().findViewsEntity(viewid);
            if (!tempViewsEntity.equals(compareEntity)) {
                logger.debug("start to update ViewsEntity .");
                getViewsEntityJpaController().edit(tempViewsEntity);
            }
        } else {

            getViewsEntityJpaController().create(tempViewsEntity);
            viewid = getViewsEntityJpaController().findViewsEntityByModuleAndIcafeProject(valuePairs.get("icafeModule"), valuePairs.get("icafeProject")).get(0);
        }
        return getViewsEntityJpaController().findViewsEntity(viewid);
    }

    private ProjectsEntity updateOrCreateProjectsEntity(Map<String, String> valuePairs, HudsonsEntity hudsonsEntity, ViewsEntity viewsEntity) throws Exception {
        logger.debug("start to updateOrCreateProjectsEntity .");
        Integer projectId;
        ProjectsEntity tempProjectsEntity = new ProjectsEntity();
        tempProjectsEntity.setChildProjects(valuePairs.get("child_projects"));
        tempProjectsEntity.setParentProjects(valuePairs.get("parent_projct"));
        tempProjectsEntity.setProjectName(valuePairs.get("projectName"));
        tempProjectsEntity.setType(valuePairs.get("projectType"));
        tempProjectsEntity.setUrl(valuePairs.get("projectUrl"));
        //tempProjectsEntity.setViewsByViewId(viewsEntity);
        tempProjectsEntity.setHudsonsByHudsonId(hudsonsEntity);
        if (getProjectsEntityJpaController().findProjectsEntityByHudsonIdAndName(hudsonsEntity.getId(), valuePairs.get("projectName")).size() != 0) {

            projectId = getProjectsEntityJpaController().findProjectsEntityByHudsonIdAndName(hudsonsEntity.getId(), valuePairs.get("projectName")).get(0);

            //for update
            tempProjectsEntity.setId(projectId);
            ProjectsEntity compareEntity = getProjectsEntityJpaController().findProjectsEntity(projectId);
            if (!tempProjectsEntity.equals(compareEntity)) {
                logger.debug("start to update ProjectsEntity .");
                getProjectsEntityJpaController().edit(tempProjectsEntity);
            }
        } else {

            getProjectsEntityJpaController().create(tempProjectsEntity);
            projectId = getProjectsEntityJpaController().findProjectsEntityByHudsonIdAndName(hudsonsEntity.getId(), valuePairs.get("projectName")).get(0);
        }
        return getProjectsEntityJpaController().findProjectsEntity(projectId);
    }

    private BuildsEntity createBuildsEntity(Map<String, String> valuePairs, HudsonsEntity hudsonsEntity, ViewsEntity viewsEntity, ProjectsEntity projectsEntity) throws Exception {
        logger.debug("start to createBuildsEntity .");
        Integer buildId = 0;
        BuildsEntity buildsEntity = new BuildsEntity();
        buildsEntity.setAuthor(valuePairs.get("cause_action_user"));
        buildsEntity.setBuildDate(Timestamp.valueOf(valuePairs.get("build_data")));
        buildsEntity.setBuildOn(valuePairs.get("build_on"));
        buildsEntity.setBuildNum(Integer.parseInt(valuePairs.get("build_num")));
        buildsEntity.setCauseAction(valuePairs.get("cause_action"));
        buildsEntity.setDuration(Integer.parseInt(valuePairs.get("duration")));
        buildsEntity.setProjectsByProjectId(projectsEntity);
        buildsEntity.setResult(valuePairs.get("result"));
        buildsEntity.setFailcount(Integer.parseInt(valuePairs.get("failCount")));
        buildsEntity.setSkipcount(Integer.parseInt(valuePairs.get("skipCount")));
        buildsEntity.setTotalcount(Integer.parseInt(valuePairs.get("totalCount")));
        if (getBuildsEntityJpaController().findBuildsByBuildNumberAndProjectId(projectsEntity, Integer.parseInt(valuePairs.get("build_num"))).size() != 0) {
            buildId = getBuildsEntityJpaController().findBuildsByBuildNumberAndProjectId(projectsEntity, Integer.parseInt(valuePairs.get("build_num"))).get(0);
            buildsEntity.setId(buildId);
            BuildsEntity compareEntity = getBuildsEntityJpaController().findBuildsEntity(buildId);
            if (!buildsEntity.equals(compareEntity)) {
                logger.debug("start to update build entity  .");
                getBuildsEntityJpaController().edit(buildsEntity);
            }
        } else {
            getBuildsEntityJpaController().create(buildsEntity);
            buildId = getBuildsEntityJpaController().findBuildsByBuildNumberAndProjectId(projectsEntity, Integer.parseInt(valuePairs.get("build_num"))).get(0);
        }
        return getBuildsEntityJpaController().findBuildsEntity(buildId);


    }

    protected void updatePluginTable(Map<String, String> valuePairs, HudsonsEntity hudsonsEntity, ViewsEntity viewsEntity, ProjectsEntity projectsEntity, BuildsEntity buildsEntity) throws Exception {

    }

    public void setHudsonsJpaController(HudsonsEntityJpaController hudsonsJpaController) {
        this.hudsonsJpaController = hudsonsJpaController;
    }

    public void setViewsEntityJpaController(ViewsEntityJpaController viewsEntityJpaController) {
        this.viewsEntityJpaController = viewsEntityJpaController;
    }

    public void setProjectsEntityJpaController(ProjectsEntityJpaController projectsEntityJpaController) {
        this.projectsEntityJpaController = projectsEntityJpaController;
    }

    public void setBuildsEntityJpaController(BuildsEntityJpaController buildsEntityJpaController) {
        this.buildsEntityJpaController = buildsEntityJpaController;
    }

    public HudsonsEntityJpaController getHudsonsJpaController() {
        return hudsonsJpaController;
    }

    public ViewsEntityJpaController getViewsEntityJpaController() {
        return viewsEntityJpaController;
    }

    public ProjectsEntityJpaController getProjectsEntityJpaController() {
        return projectsEntityJpaController;
    }

    public BuildsEntityJpaController getBuildsEntityJpaController() {
        return buildsEntityJpaController;
    }
}
